﻿using UnityEngine;
using UnityEditor;
using System.Reflection;
using Extensions;
using System;

namespace TC
{
    class NodeInfoInspector : EditorWindow 
    {
        private FlowNodeSurface targetSurf;
        private FlowNode target;
        private bool willRepaint = false;
        public bool invokeParentRepaint = false;
        private GUIStyle _headerStyle;
        private GUIStyle headerStyle
        {
            get
            {
                if (_headerStyle == default)
                {
                    _headerStyle = new GUIStyle("label");
                    _headerStyle.fontSize = 26;
                    _headerStyle.alignment = TextAnchor.MiddleCenter;
                    _headerStyle.normal.textColor = EditorGUIUtility.isProSkin ? Color.white : Color.black;
                    _headerStyle.margin = new RectOffset(5, 5, 5, 5);
                    _headerStyle.padding = new RectOffset(0, 0, 3, 3);
                    _headerStyle.stretchWidth = true;
                }
                return _headerStyle;
            }
        }

        private void Awake()
        {
            EventCenter.Instance.Register<FlowNodeSurface>((int)EventCenterNumber.OnActiveNodeChg, OnTargetChange);   
        }

        private void OnDestroy()
        {
            EventCenter.Instance.Unregister<FlowNodeSurface>((int)EventCenterNumber.OnActiveNodeChg, OnTargetChange);
        }

        public void OnTargetChange(FlowNodeSurface targetSurf)
        {
            if (targetSurf != null)
            {
                this.targetSurf = targetSurf;
                target = targetSurf.target;
            }
            else
            {
                this.targetSurf = null;
                target = null;
            }
            willRepaint = true;
        }

        private void OnGUI()
        {
            //Debug.Log(GUI.changed);
            GUILayout.BeginArea(new Rect(0, 0, position.width, position.height));
            GUILayout.Space(5);
            if (target == null)
            {
                GUILayout.Label("No node selected..");
            }
            else
            {
                //TODO 想办法储存 or 减少反射的次数
                DrawInspectorHeader();
                GUILayoutHelper.SeparatorLine();
                DrawNodeValues();
            }
            GUILayout.EndArea();
        }

        private void Update()
        {
            if (willRepaint)
            {
                Repaint();
                willRepaint = false;
            }
        }


        #region 绘制

        public void DrawInspectorHeader()
        {
            // node name
            GUILayout.BeginHorizontal();
            GUILayout.Box(targetSurf.showName, headerStyle);
            GUILayout.EndHorizontal();

            // description
            DescriptionAttribute[] attributes = (DescriptionAttribute[])target.GetType().GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attributes.Length > 0 && attributes[0] != null)
            {
                GUILayout.BeginHorizontal();
                EditorGUILayout.HelpBox(attributes[0].description, MessageType.Info, true);
                GUILayout.EndHorizontal();
            }
        }

        public void DrawNodeValues()
        {
            EditorGUI.BeginChangeCheck();
            foreach (var item in target.inputPorts)
            {
                var port = item.Value;
                if (port.GetType().IsGenericType)
                {
                    var targetInputType = typeof(ValueInput<>).MakeGenericType(port.GetType().GenericTypeArguments[0]);
                    if (port.GetType() == targetInputType)
                    {
                        FieldInfo defaultValueInfo = port.GetType().GetField("defaultValue");
                        var defaultValue = defaultValueInfo.GetValue(port);
                        var defaultValueType = port.GetType().GenericTypeArguments[0];
                        GUILayout.BeginHorizontal();
                        if (defaultValueType == typeof(Vector2))
                        {
                            defaultValue = EditorGUILayout.Vector2Field(item.Key, (Vector2)defaultValue);
                        }
                        else if (defaultValueType == typeof(Vector3))
                        {
                            defaultValue = EditorGUILayout.Vector3Field(item.Key, (Vector3)defaultValue);
                        }
                        else if (defaultValueType == typeof(Vector4))
                        {
                            defaultValue = EditorGUILayout.Vector4Field(item.Key, (Vector4)defaultValue);
                        }
                        else if (defaultValueType == typeof(bool))
                        {
                            defaultValue = EditorGUILayout.Toggle(item.Key, (bool)defaultValue);
                        }
                        else if (defaultValueType == typeof(int))
                        {
                            defaultValue = EditorGUILayout.IntField(item.Key, (int)defaultValue);
                        }
                        else if (defaultValueType == typeof(float))
                        {
                            defaultValue = EditorGUILayout.FloatField(item.Key, (float)defaultValue);
                        }
                        else if (defaultValueType == typeof(long))
                        {
                            defaultValue = EditorGUILayout.LongField(item.Key, (long)defaultValue);
                        }
                        else if (defaultValueType == typeof(double))
                        {
                            defaultValue = EditorGUILayout.DoubleField(item.Key, (double)defaultValue);
                        }
                        else if (defaultValueType == typeof(string))
                        {
                            defaultValue = EditorGUILayout.TextField(item.Key, (string)defaultValue);
                        }
                        else if (defaultValueType == typeof(Color))
                        {
                            defaultValue = EditorGUILayout.ColorField(item.Key, (Color)defaultValue);
                        }
                        else if (defaultValueType == typeof(AnimationCurve))
                        {
                            if (defaultValue == null)
                            {
                                defaultValue = AnimationCurve.Linear(0, 0, 0, 0);
                                defaultValueInfo.SetValue(port, defaultValue);
                            }
                            defaultValue = EditorGUILayout.CurveField(item.Key, (AnimationCurve)defaultValue);
                        }
                        else if (defaultValueType.IsEnum)
                        {
                            defaultValue = EditorGUILayout.EnumPopup(item.Key, (Enum)defaultValue);
                        }
                        else if (defaultValueType == typeof(Rect))
                        {
                            defaultValue = EditorGUILayout.RectField(item.Key, (Rect)defaultValue);
                        }
                        else if (defaultValueType.IsSubclassOf(typeof(UnityEngine.Object)))
                        {
                            defaultValue = EditorGUILayout.ObjectField(item.Key, (UnityEngine.Object)defaultValue, defaultValueType, true);
                        }

                        GUILayout.EndHorizontal();
                        defaultValueInfo.SetValue(port, defaultValue);
                    }
                }
            }
            if (EditorGUI.EndChangeCheck())
            {
                invokeParentRepaint = true;
                EventCenter.Instance.SendEvent<FlowNode>((int)EventCenterNumber.OnNodeValueChg, target);
            }
        }

        #endregion

    }
}
